//工厂模式 （Factory Pattern），根据不同的输入返回不同类的实例，一般用来创建同一类对象。工厂方式的主要思想是将对象的创建与对象的实现分离。

/* 工厂类 */
class Factory {
    static getInstance(type) {
        switch (type) {
            case 'Product1':
                return new Product1()
            case 'Product2':
                return new Product2()
            default:
                throw new Error('当前没有这个产品')
        }
    }
}

/* 产品类1 */
class Product1 {
    constructor() { this.type = 'Product1' }
    
    operate() { console.log(this.type) }
}

/* 产品类2 */
class Product2 {
    constructor() { this.type = 'Product2' }
    
    operate() { console.log(this.type) }
}

const prod1 = Factory.getInstance('Product1')
prod1.operate()																	// 输出: Product1
const prod2 = Factory.getInstance('Product3')		// 输出: Error 当前没有这个产品


// Vue
createElement('h3', { class: 'main-title' }, [
    createElement('img', { class: 'avatar', attrs: { src: '../avatar.jpg' } }),
    createElement('p', { class: 'user-desc' }, '长得帅老的快，长得丑活得久')
])



function createElement(tag, data, children) {
  	return new Vnode(tag, data, children)
}


//4.2 vue-router 源码中的工厂模式
//工厂模式在源码中应用频繁，以 vue-router 中的源码为例，代码位置：vue-router/src/index.js

// src/index.js
export default class VueRouter {
    constructor(options) {
        this.mode = mode	// 路由模式
        
        switch (mode) {           // 简单工厂
            case 'history':       // history 方式
                this.history = new HTML5History(this, options.base)
                break
            case 'hash':          // hash 方式
                this.history = new HashHistory(this, options.base, this.fallback)
                break
            case 'abstract':      // abstract 方式
                this.history = new AbstractHistory(this, options.base)
                break
            default:
                // ... 初始化失败报错
        }
    }
}

//稍微解释一下这里的源码。mode 是路由创建的模式，这里有三种 History、Hash、Abstract，前两种我们已经很熟悉了，History 是 H5 的路由方式，Hash 是路由中带 # 的路由方式，Abstract 代表非浏览器环境中路由方式，比如 Node、weex 等；this.history 用来保存路由实例，vue-router 中使用了工厂模式的思想来获得响应路由控制类的实例。